 /***********************************************************
 *  File_Name  : XJTxtLog.h
 *  File_Path   : 
 *  File_Encode : UTF8
 *  Description : 文本日志类
 *  
 *  OS : Linux, UNIX
 *  LastVersion  : 20130723
 *      
 *  Author      : LiXiujie(李秀杰)
 *  Date        : 2014-4-17
 *  Version     : 20130417
 *  Description :
 *                
 *  Edit Author : 
 *  Edit Date   : 
 *  Version     : 
 *  Description :
 *                
 ***********************************************************/
#ifndef XJTXTLOG_H_
#define XJTXTLOG_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <string>
#include <stdarg.h>
#include <errno.h>
#include <iostream>

#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/stat.h>
#include <fcntl.h>

using namespace std;

namespace XJUtilClass{

#define XJTXTLOG_CACHESIZE 2*1024
#define XJTXTLOG_CACHEMAXSIZE 32*1024


typedef void* (*XJTXTLOG_THREADFUN)(void *);

enum XJTxtLogReturn{
	XJTXTLOG_OK = 0,
	XJTXTLOG_ERROR_MALLOC,
	XJTXTLOG_ERROR_NULL_FILE,
	XJTXTLOG_ERROR_FILE_OPEN,
	XJTXTLOG_ERROR_NO_CFG,
	XJTXTLOG_ERROR_FILE_NOT_OPEN,
	XJTXTLOG_ERROR_WRITE,
	XJTXTLOG_ERROR_LEVEL,
	XJTXTLOG_ERROR_NULL,
	XJTXTLOG_ERROR_OTHER
};
enum XJTxtLogLevel{XJTXTLOG_LEVEL_DEBUG, XJTXTLOG_LEVEL_INFO, XJTXTLOG_LEVEL_WARN, XJTXTLOG_LEVEL_ERROR, XJTXTLOG_LEVEL_FATAL};
enum XJTxtLogMode{XJTXTLOG_MODE_NOCACHE, XJTXTLOG_MODE_CACHE};

class XJTxtLog {
public:

	XJTxtLog();
	XJTxtLog(XJTxtLogLevel iLevel, const char *szFilePath, const char* szFileName,
			XJTxtLogMode iMode=XJTXTLOG_MODE_NOCACHE, unsigned long ulCacheSize = XJTXTLOG_CACHESIZE);
	virtual ~XJTxtLog();
	static int Debug(XJTxtLog* pLog, const char* szFormat, ...);
	static int Info(XJTxtLog* pLog, const char* szFormat, ...);
	static int Warn(XJTxtLog* pLog, const char* szFormat, ...);
	static int Error(XJTxtLog* pLog, const char* szFormat, ...);
	static int Fatal(XJTxtLog* pLog, const char* szFormat, ...);
	int debug(const char* szFormat, ...);
	int info(const char* szFormat, ...);
	int warn(const char* szFormat, ...);
	int error(const char* szFormat, ...);
	int fatal(const char* szFormat, ...);
	int writeLog(XJTxtLogLevel iLevel, const char* szTextLog);
	void setCacheSize(unsigned long ulCacheSize);
	unsigned long getCacheSize();
	void setLevel(XJTxtLogLevel level);
	int getLevel();
	void setMode(XJTxtLogMode iMode);
	int getMode();
	void setLogFilePath(const char* szFilePath);
	const char* getLogFilePath();
	void setLogFileName(const char* szFileName);
	const char* getLogFileName();
	XJTxtLogLevel getLevelTxt(const char *szLevelTxt);
	void setFlushTimeout(unsigned int nMicro);
	unsigned int getFlushTimeout();
private:
	int writeFile();
	void GetLevelMsg(char* pMsg,XJTxtLogLevel iLevel);
	void getDataAndTime(char* pDateBuf,char* pTimeBuf);
	int CreateThread();
	static void* processThread(XJTxtLog* p);
private:
	unsigned long m_lSize;
	XJTxtLogMode  m_iMode;
	XJTxtLogLevel  m_iLevel;
	char m_szFilePath[512];
	char m_szFileName[128];
	char m_szFileAllPath[512];
	char m_szDateTime[18];
	string m_strCache;
	pthread_mutex_t m_MutexFile;
	pthread_mutex_t m_MutexStrCache;
	int m_iFile;
	bool m_IsThreadRun;
	unsigned int m_nFlushTimeout; // microseconds
	unsigned int m_nThreadRunCount;
};


#define XJTXTLOG_DEBUG(pLog, szFormat, ...) XJTxtLog::Debug(pLog, szFormat,##__VA_ARGS__)
#define XJTXTLOG_INFO(pLog,  szFormat, ...) XJTxtLog::Info(pLog,  szFormat,##__VA_ARGS__)
#define XJTXTLOG_WARN(pLog,  szFormat, ...) XJTxtLog::Warn(pLog,  szFormat,##__VA_ARGS__)
#define XJTXTLOG_ERROR(pLog, szFormat, ...) XJTxtLog::Error(pLog, szFormat,##__VA_ARGS__)
#define XJTXTLOG_FATAL(pLog, szFormat, ...) XJTxtLog::Fatal(pLog, szFormat,##__VA_ARGS__)

#define XJTXTLOG_FLF_DEBUG(pLog, szFormat, ...) XJTxtLog::Debug(pLog, "[FILE:%s][LINE:%d][FUN:%s]"szFormat, __FILE__, __LINE__ , __FUNCTION__,##__VA_ARGS__)
#define XJTXTLOG_FLF_INFO(pLog,  szFormat, ...) XJTxtLog::Info(pLog,  "[FILE:%s][LINE:%d][FUN:%s]"szFormat, __FILE__, __LINE__ , __FUNCTION__,##__VA_ARGS__)
#define XJTXTLOG_FLF_WARN(pLog,  szFormat, ...) XJTxtLog::Warn(pLog,  "[FILE:%s][LINE:%d][FUN:%s]"szFormat, __FILE__, __LINE__ , __FUNCTION__,##__VA_ARGS__)
#define XJTXTLOG_FLF_ERROR(pLog, szFormat, ...) XJTxtLog::Error(pLog, "[FILE:%s][LINE:%d][FUN:%s]"szFormat, __FILE__, __LINE__ , __FUNCTION__,##__VA_ARGS__)
#define XJTXTLOG_FLF_FATAL(pLog, szFormat, ...) XJTxtLog::Fatal(pLog, "[FILE:%s][LINE:%d][FUN:%s]"szFormat, __FILE__, __LINE__ , __FUNCTION__,##__VA_ARGS__)


} // namespace XJUtilClass

#endif /* XJTXTLOG_H_ */
